#ifndef _MEMPOOL_T_
#define _MEMPOOL_T_

#include <iostream>
#include <list>
#include <vector>
#include "memPage_t.h"
using namespace std;
class memPool_t {
public:
	memPool_t(int numOfPages = 1);
	~memPool_t();
	int getPosition();
	bool setPosition(int position);
	bool isEmpty();
	int getUsedSpace();
	int getCapacity();
	int getNumOfPages();	
	memPage_t* getFirstMemoryPage();
	memPage_t* getLastMemoryPage();
	memPage_t* getCurrentMemoryPage();
	
	template <class T>
	void read(T &obj, int size)
	{
		memPage_t* currentPage = getCurrentMemoryPage();
		int		   currentPagePosition = currentPage->getPosition();
		byte* mem = new byte[size];
		int i = 0;

		while (currentPagePosition < currentPage ->getActualSize() && (i < size))
		{
			mem[i] = (*(*currentPage).read());
			setPosition(_current + 1);
			i++;
			currentPage = getCurrentMemoryPage();
			currentPagePosition = currentPage->getPosition();
		}
		
		memcpy(&obj,mem,size);
		delete[] mem;
	}
	
	template <class T>
	void write(const T &obj, int size)
	{	
		if ( (_capacity - _current) < size) /* if we need to add pages*/
		{
			int numOfBytesToAdd = size - (_capacity - _current);
			int numOfPageToAdd	= numOfBytesToAdd / _defaultPageSize + 1;
			addMemoryPages(numOfPageToAdd);
		}
		
		int numOfBytesWriten = 0;
		int	currentPagePosition;
		int	numOfBytesToWriteInPage;
		
		memPage_t*	currentPage;
		byte* mem = new byte[size];
		memcpy(mem,&obj,size);
		
		while (numOfBytesWriten < size)
		{
			currentPage = getCurrentMemoryPage();
			currentPagePosition = currentPage->getPosition();
				
			if ((currentPage->getCapacity() - currentPagePosition) >= size)
				numOfBytesToWriteInPage = size - numOfBytesWriten;
			else 
				numOfBytesToWriteInPage = currentPage->getCapacity() - currentPagePosition ;

			currentPage->write(mem + numOfBytesWriten,numOfBytesToWriteInPage,currentPage->getPosition());
			numOfBytesWriten += numOfBytesToWriteInPage;
			_usedSpace += numOfBytesToWriteInPage;
			setPosition(_current+numOfBytesToWriteInPage);
			
		}
		delete[] mem;

	};
	
	void addMemoryPages(int count);
	static int getDefaultPageSize();
	static void setDefaultPageSize(int size);

private:
	memPage_t* CurrentPageAndPosition(int& placeInPage);
	int _numOfPages;
	int _usedSpace;
	int _current;
	int _capacity;
	static int _defaultPageSize;
	vector<memPage_t *> _pages;
	memPool_t(const memPool_t &other);
};



#endif // _MEMPOOL_T_